home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb.new / sprite / gdb / RCS / mips-tdep.c,v < prev    next >
Encoding:
Text File  |  1991-09-03  |  22.2 KB  |  713 lines

  1. head     1.1;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    jhh:1.1; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.1
  10. date     91.09.03.12.09.03;  author jhh;  state Exp;
  11. branches ;
  12. next     ;
  13.  
  14.  
  15. desc
  16. @@
  17.  
  18.  
  19.  
  20. 1.1
  21. log
  22. @Initial revision
  23. @
  24. text
  25. @/* Work with core dump and executable files, for GDB on MIPS. 
  26.    This code would be in core.c if it weren't machine-dependent. */
  27.  
  28. /* Low level interface to ptrace, for GDB when running under Unix.
  29.    Copyright (C) 1988, 1989, 1990  Free Software Foundation, Inc.
  30.    Contributed by Alessandro Forin(af@@cs.cmu.edu) at CMU
  31.    and by Per Bothner(bothner@@cs.wisc.edu) at U.Wisconsin.
  32.  
  33. This file is part of GDB.
  34.  
  35. This program is free software; you can redistribute it and/or modify
  36. it under the terms of the GNU General Public License as published by
  37. the Free Software Foundation; either version 2 of the License, or
  38. (at your option) any later version.
  39.  
  40. This program is distributed in the hope that it will be useful,
  41. but WITHOUT ANY WARRANTY; without even the implied warranty of
  42. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  43. GNU General Public License for more details.
  44.  
  45. You should have received a copy of the GNU General Public License
  46. along with this program; if not, write to the Free Software
  47. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  48.  
  49. /* FIXME: Can a MIPS porter/tester determine which of these include
  50.    files we still need?   -- gnu@@cygnus.com */
  51. #include <stdio.h>
  52. #include <mips/inst.h>
  53. #include "defs.h"
  54. #include "param.h"
  55. #include "frame.h"
  56. #include "inferior.h"
  57. #include "symtab.h"
  58. #include "value.h"
  59. #include "gdbcmd.h"
  60.  
  61. #ifdef USG
  62. #include <sys/types.h>
  63. #endif
  64.  
  65. #include <sys/param.h>
  66. #include <sys/dir.h>
  67. #include <signal.h>
  68. #include <sys/ioctl.h>
  69.  
  70. #include "gdbcore.h"
  71.  
  72. #ifndef    MIPSMAGIC
  73. #ifdef MIPSEL
  74. #define MIPSMAGIC    MIPSELMAGIC
  75. #else
  76. #define MIPSMAGIC    MIPSEBMAGIC
  77. #endif
  78. #endif
  79.  
  80. #define VM_MIN_ADDRESS (unsigned)0x400000
  81.  
  82. #include <sys/user.h>        /* After a.out.h  */
  83. #include <sys/file.h>
  84. #include <sys/stat.h>
  85.  
  86.  
  87. #define PROC_LOW_ADDR(proc) ((proc)->adr) /* least address */
  88. #define PROC_HIGH_ADDR(proc) ((proc)->pad2) /* upper address bound */
  89. #define PROC_FRAME_OFFSET(proc) ((proc)->framesize)
  90. #define PROC_FRAME_REG(proc) ((proc)->framereg)
  91. #define PROC_REG_MASK(proc) ((proc)->regmask)
  92. #define PROC_FREG_MASK(proc) ((proc)->fregmask)
  93. #define PROC_REG_OFFSET(proc) ((proc)->regoffset)
  94. #define PROC_FREG_OFFSET(proc) ((proc)->fregoffset)
  95. #define PROC_PC_REG(proc) ((proc)->pcreg)
  96. #define PROC_SYMBOL(proc) (*(struct symbol**)&(proc)->isym)
  97. #define _PROC_MAGIC_ 0x0F0F0F0F
  98. #define PROC_DESC_IS_DUMMY(proc) ((proc)->isym == _PROC_MAGIC_)
  99. #define SET_PROC_DESC_IS_DUMMY(proc) ((proc)->isym = _PROC_MAGIC_)
  100.  
  101. struct linked_proc_info
  102. {
  103.   struct mips_extra_func_info info;
  104.   struct linked_proc_info *next;
  105. } * linked_proc_desc_table = NULL;
  106.  
  107.  
  108. #define READ_FRAME_REG(fi, regno) read_next_frame_reg((fi)->next, regno)
  109.  
  110. int
  111. read_next_frame_reg(fi, regno)
  112.      FRAME fi;
  113.      int regno;
  114. {
  115. #define SIGFRAME_BASE   sizeof(struct sigcontext)
  116. #define SIGFRAME_PC_OFF (-SIGFRAME_BASE+ 2*sizeof(int))
  117. #define SIGFRAME_SP_OFF (-SIGFRAME_BASE+32*sizeof(int))
  118. #define SIGFRAME_RA_OFF (-SIGFRAME_BASE+34*sizeof(int))
  119.   for (; fi; fi = fi->next)
  120.       if (in_sigtramp(fi->pc, 0)) {
  121.       /* No idea if this code works. --PB. */
  122.       int offset;
  123.       if (regno == PC_REGNUM) offset = SIGFRAME_PC_OFF;
  124.       else if (regno == RA_REGNUM) offset = SIGFRAME_RA_OFF;
  125.       else if (regno == SP_REGNUM) offset = SIGFRAME_SP_OFF;
  126.       else return 0;
  127.       return read_memory_integer(fi->frame + offset, 4);
  128.       }
  129.       else if (regno == SP_REGNUM) return fi->frame;
  130.       else if (fi->saved_regs->regs[regno])
  131.     return read_memory_integer(fi->saved_regs->regs[regno], 4);
  132.   return read_register(regno);
  133. }
  134.  
  135. int
  136. mips_frame_saved_pc(frame)
  137.      FRAME frame;
  138. {
  139.   mips_extra_func_info_t proc_desc = (mips_extra_func_info_t)frame->proc_desc;
  140.   int pcreg = proc_desc ? PROC_PC_REG(proc_desc) : RA_REGNUM;
  141.   if (proc_desc && PROC_DESC_IS_DUMMY(proc_desc))
  142.       return read_memory_integer(frame->frame - 4, 4);
  143. #if 0
  144.   /* If in the procedure prologue, RA_REGNUM might not have been saved yet.
  145.    * Assume non-leaf functions start with:
  146.    *    addiu $sp,$sp,-frame_size
  147.    *    sw $ra,ra_offset($sp)
  148.    * This if the pc is pointing at either of these instructions,
  149.    * then $ra hasn't been trashed.
  150.    * If the pc has advanced beyond these two instructions,
  151.    * then $ra has been saved.
  152.    * critical, and much more complex. Handling $ra is enough to get
  153.    * a stack trace, but some register values with be wrong.
  154.    */
  155.   if (frame->proc_desc && frame->pc < PROC_LOW_ADDR(proc_desc) + 8)
  156.       return read_register(pcreg);
  157. #endif
  158.   return read_next_frame_reg(frame, pcreg);
  159. }
  160.  
  161. static struct mips_extra_func_info temp_proc_desc;
  162. static struct frame_saved_regs temp_saved_regs;
  163.  
  164. CORE_ADDR heuristic_proc_start(pc)
  165.     CORE_ADDR pc;
  166. {
  167.  
  168.     CORE_ADDR start_pc = pc;
  169.     CORE_ADDR fence = start_pc - 10000;
  170.     if (fence < VM_MIN_ADDRESS) fence = VM_MIN_ADDRESS;
  171.     /* search back for previous return */
  172.     for (start_pc -= 4; ; start_pc -= 4)
  173.     if (start_pc < fence) return 0; 
  174.     else if (ABOUT_TO_RETURN(start_pc))
  175.         break;
  176.  
  177.     start_pc += 8; /* skip return, and its delay slot */
  178. #if 0
  179.     /* skip nops (usually 1) 0 - is this */
  180.     while (start_pc < pc && read_memory_integer (start_pc, 4) == 0)
  181.     start_pc += 4;
  182. #endif
  183.     return start_pc;
  184. }
  185.  
  186. mips_extra_func_info_t
  187. heuristic_proc_desc(start_pc, limit_pc, next_frame)
  188.     CORE_ADDR start_pc, limit_pc;
  189.     FRAME next_frame;
  190. {
  191.     CORE_ADDR sp = next_frame ? next_frame->frame : read_register (SP_REGNUM);
  192.     CORE_ADDR cur_pc;
  193.     int frame_size;
  194.     int has_frame_reg = 0;
  195.     int reg30; /* Value of $r30. Used by gcc for frame-pointer */
  196.     unsigned long reg_mask = 0;
  197.  
  198.     if (start_pc == 0) return NULL;
  199.     bzero(&temp_proc_desc, sizeof(temp_proc_desc));
  200.     bzero(&temp_saved_regs, sizeof(struct frame_saved_regs));
  201.     if (start_pc + 200 < limit_pc) limit_pc = start_pc + 200;
  202.   restart:
  203.     frame_size = 0;
  204.     for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4) {
  205.     unsigned long word;
  206.     int status;
  207.  
  208.     status = read_memory_nobpt (cur_pc, &word, 4); 
  209.     if (status) memory_error (status, cur_pc); 
  210.     if ((word & 0xFFFF0000) == 0x27bd0000) /* addiu $sp,$sp,-i */
  211.         frame_size += (-word) & 0xFFFF;
  212.     else if ((word & 0xFFFF0000) == 0x23bd0000) /* addu $sp,$sp,-i */
  213.         frame_size += (-word) & 0xFFFF;
  214.     else if ((word & 0xFFE00000) == 0xafa00000) { /* sw reg,offset($sp) */
  215.         int reg = (word & 0x001F0000) >> 16;
  216.         reg_mask |= 1 << reg;
  217.         temp_saved_regs.regs[reg] = sp + (short)word;
  218.     }
  219.     else if ((word & 0xFFFF0000) == 0x27be0000) { /* addiu $30,$sp,size */
  220.         if ((unsigned short)word != frame_size)
  221.         reg30 = sp + (unsigned short)word;
  222.         else if (!has_frame_reg) {
  223.         int alloca_adjust;
  224.         has_frame_reg = 1;
  225.         reg30 = read_next_frame_reg(next_frame, 30);
  226.         alloca_adjust = reg30 - (sp + (unsigned short)word);
  227.         if (alloca_adjust > 0) {
  228.             /* FP > SP + frame_size. This may be because
  229.             /* of an alloca or somethings similar.
  230.              * Fix sp to "pre-alloca" value, and try again.
  231.              */
  232.             sp += alloca_adjust;
  233.             goto restart;
  234.         }
  235.         }
  236.     }
  237.     else if ((word & 0xFFE00000) == 0xafc00000) { /* sw reg,offset($30) */
  238.         int reg = (word & 0x001F0000) >> 16;
  239.         reg_mask |= 1 << reg;
  240.         temp_saved_regs.regs[reg] = reg30 + (short)word;
  241.     }
  242.     }
  243.     if (has_frame_reg) {
  244.     PROC_FRAME_REG(&temp_proc_desc) = 30;
  245.     PROC_FRAME_OFFSET(&temp_proc_desc) = 0;
  246.     }
  247.     else {
  248.     PROC_FRAME_REG(&temp_proc_desc) = SP_REGNUM;
  249.     PROC_FRAME_OFFSET(&temp_proc_desc) = frame_size;
  250.     }
  251.     PROC_REG_MASK(&temp_proc_desc) = reg_mask;
  252.     PROC_PC_REG(&temp_proc_desc) = RA_REGNUM;
  253.     return &temp_proc_desc;
  254. }
  255.  
  256. mips_extra_func_info_t
  257. find_proc_desc(pc, next_frame)
  258.     CORE_ADDR pc;
  259.     FRAME next_frame;
  260. {
  261.   mips_extra_func_info_t proc_desc;
  262.   extern struct block *block_for_pc();
  263.   struct block   *b = block_for_pc(pc);
  264.  
  265.   struct symbol *sym =
  266.       b ? lookup_symbol(".gdbinfo.", b, LABEL_NAMESPACE, 0, NULL) : NULL;
  267.   if (sym != NULL)
  268.     {
  269.     /* IF this is the topmost frame AND
  270.      * (this proc does not have debugging information OR
  271.      * the PC is in the procedure prologue)
  272.      * THEN create a "hueristic" proc_desc (by analyzing
  273.      * the actual code) to replace the "official" proc_desc.
  274.      */
  275.     proc_desc = (struct mips_extra_func_info *)sym->value.value;
  276.     if (next_frame == NULL) {
  277.         struct symtab_and_line val;
  278.         struct symbol *proc_symbol =
  279.         PROC_DESC_IS_DUMMY(proc_desc) ? 0 : PROC_SYMBOL(proc_desc);
  280.         if (proc_symbol) {
  281.         val = find_pc_line (BLOCK_START
  282.                     (SYMBOL_BLOCK_VALUE(proc_symbol)),
  283.                     0);
  284.         val.pc = val.end ? val.end : pc;
  285.         }
  286.         if (!proc_symbol || pc < val.pc) {
  287.         mips_extra_func_info_t found_heuristic =
  288.             heuristic_proc_desc(PROC_LOW_ADDR(proc_desc),
  289.                     pc, next_frame);
  290.         if (found_heuristic) proc_desc = found_heuristic;
  291.         }
  292.     }
  293.     }
  294.   else
  295.     {
  296.       register struct linked_proc_info *link;
  297.       for (link = linked_proc_desc_table; link; link = link->next)
  298.       if (PROC_LOW_ADDR(&link->info) <= pc
  299.           && PROC_HIGH_ADDR(&link->info) > pc)
  300.           return &link->info;
  301.       proc_desc =
  302.       heuristic_proc_desc(heuristic_proc_start(pc), pc, next_frame);
  303.     }
  304.   return proc_desc;
  305. }
  306.  
  307. mips_extra_func_info_t cached_proc_desc;
  308.  
  309. FRAME_ADDR mips_frame_chain(frame)
  310.     FRAME frame;
  311. {
  312.     extern CORE_ADDR startup_file_start;    /* From blockframe.c */
  313.     mips_extra_func_info_t proc_desc;
  314.     CORE_ADDR saved_pc = FRAME_SAVED_PC(frame);
  315.     if (startup_file_start)
  316.       { /* has at least the __start symbol */
  317.     if (saved_pc == 0 || !outside_startup_file (saved_pc)) return 0;
  318.       }
  319.     else
  320.       { /* This hack depends on the internals of __start. */
  321.     /* We also assume the breakpoints are *not* inserted */
  322.         if (saved_pc == 0
  323.         || read_memory_integer (saved_pc + 8, 4) & 0xFC00003F == 0xD)
  324.         return 0;  /* break */
  325.       }
  326.     proc_desc = find_proc_desc(saved_pc, frame);
  327.     if (!proc_desc) return 0;
  328.     cached_proc_desc = proc_desc;
  329.     return read_next_frame_reg(frame, PROC_FRAME_REG(proc_desc))
  330.     + PROC_FRAME_OFFSET(proc_desc);
  331. }
  332.  
  333. void
  334. init_extra_frame_info(fci)
  335.      struct frame_info *fci;
  336. {
  337.   extern struct obstack frame_cache_obstack;
  338.   /* Use proc_desc calculated in frame_chain */
  339.   mips_extra_func_info_t proc_desc = fci->next ? cached_proc_desc :
  340.       find_proc_desc(fci->pc, fci->next);
  341.   fci->saved_regs = (struct frame_saved_regs*)
  342.     obstack_alloc (&frame_cache_obstack, sizeof(struct frame_saved_regs));
  343.   bzero(fci->saved_regs, sizeof(struct frame_saved_regs));
  344.   fci->proc_desc =
  345.       proc_desc == &temp_proc_desc ? (char*)NULL : (char*)proc_desc;
  346.   if (proc_desc)
  347.     {
  348.       int ireg;
  349.       CORE_ADDR reg_position;
  350.       unsigned long mask;
  351.       /* r0 bit means kernel trap */
  352.       int kernel_trap = PROC_REG_MASK(proc_desc) & 1;
  353.  
  354.       /* Fixup frame-pointer - only needed for top frame */
  355.       /* This may not be quite right, if procedure has a real frame register */
  356.       if (fci->pc == PROC_LOW_ADDR(proc_desc))
  357.       fci->frame = read_register (SP_REGNUM);
  358.       else
  359.       fci->frame = READ_FRAME_REG(fci, PROC_FRAME_REG(proc_desc))
  360.           + PROC_FRAME_OFFSET(proc_desc);
  361.  
  362.       if (proc_desc == &temp_proc_desc)
  363.       *fci->saved_regs = temp_saved_regs;
  364.       else
  365.       {
  366.       /* find which general-purpose registers were saved */
  367.       reg_position = fci->frame + PROC_REG_OFFSET(proc_desc);
  368.       mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK(proc_desc);
  369.       for (ireg= 31; mask; --ireg, mask <<= 1)
  370.           if (mask & 0x80000000)
  371.           {
  372.           fci->saved_regs->regs[ireg] = reg_position;
  373.           reg_position -= 4;
  374.           }
  375.       /* find which floating-point registers were saved */
  376.       reg_position = fci->frame + PROC_FREG_OFFSET(proc_desc);
  377.       /* The freg_offset points to where the first *double* register is saved.
  378.        * So skip to the high-order word. */
  379.       reg_position += 4;
  380.       mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK(proc_desc);
  381.       for (ireg = 31; mask; --ireg, mask <<= 1)
  382.           if (mask & 0x80000000)
  383.           {
  384.           fci->saved_regs->regs[32+ireg] = reg_position;
  385.           reg_position -= 4;
  386.           }
  387.       }
  388.  
  389.       /* hack: if argument regs are saved, guess these contain args */
  390.       if ((PROC_REG_MASK(proc_desc) & 0xF0) == 0) fci->num_args = -1;
  391.       else if ((PROC_REG_MASK(proc_desc) & 0x80) == 0) fci->num_args = 4;
  392.       else if ((PROC_REG_MASK(proc_desc) & 0x40) == 0) fci->num_args = 3;
  393.       else if ((PROC_REG_MASK(proc_desc) & 0x20) == 0) fci->num_args = 2;
  394.       else if ((PROC_REG_MASK(proc_desc) & 0x10) == 0) fci->num_args = 1;
  395.  
  396.       fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[RA_REGNUM];
  397.     }
  398.   if (fci->next == 0)
  399.       supply_register(FP_REGNUM, &fci->frame);
  400. }
  401.  
  402.  
  403. CORE_ADDR mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
  404.   int nargs;
  405.   value *args;
  406.   CORE_ADDR sp;
  407.   int struct_return;
  408.   CORE_ADDR struct_addr;
  409. {
  410.   CORE_ADDR buf;
  411.   register i;
  412.   int accumulate_size = struct_return ? 4 : 0;
  413.   struct mips_arg { char *contents; int len; int offset; };
  414.   struct mips_arg *mips_args =
  415.       (struct mips_arg*)alloca(nargs * sizeof(struct mips_arg));
  416.   register struct mips_arg *m_arg;
  417.   for (i = 0, m_arg = mips_args; i < nargs; i++, m_arg++) {
  418.     extern value value_arg_coerce();
  419.     value arg = value_arg_coerce (args[i]);
  420.     m_arg->len = TYPE_LENGTH (VALUE_TYPE (arg));
  421.     /* This entire mips-specific routine is because doubles must be aligned
  422.      * on 8-byte boundaries. It still isn't quite right, because MIPS decided
  423.      * to align 'struct {int a, b}' on 4-byte boundaries (even though this
  424.      * breaks their varargs implementation...). A correct solution
  425.      * requires an simulation of gcc's 'alignof' (and use of 'alignof'
  426.      * in stdarg.h/varargs.h).
  427.      */
  428.     if (m_arg->len > 4) accumulate_size = (accumulate_size + 7) & -8;
  429.     m_arg->offset = accumulate_size;
  430.     accumulate_size = (accumulate_size + m_arg->len + 3) & -4;
  431.     m_arg->contents = VALUE_CONTENTS(arg);
  432.   }
  433.   accumulate_size = (accumulate_size + 7) & (-8);
  434.   if (accumulate_size < 16) accumulate_size = 16; 
  435.   sp -= accumulate_size;
  436.   for (i = nargs; m_arg--, --i >= 0; )
  437.     write_memory(sp + m_arg->offset, m_arg->contents, m_arg->len);
  438.   if (struct_return) {
  439.     buf = struct_addr;
  440.     write_memory(sp, &buf, sizeof(CORE_ADDR));
  441. }
  442.   return sp;
  443. }
  444.  
  445. /* MASK(i,j) == (1<<i) + (1<<(i+1)) + ... + (1<<j)). Assume i<=j<31. */
  446. #define MASK(i,j) ((1 << (j)+1)-1 ^ (1 << (i))-1)
  447.  
  448. void
  449. mips_push_dummy_frame()
  450. {
  451.   int ireg;
  452.   struct linked_proc_info *link = (struct linked_proc_info*)
  453.       xmalloc(sizeof(struct linked_proc_info));
  454.   mips_extra_func_info_t proc_desc = &link->info;
  455.   CORE_ADDR sp = read_register (SP_REGNUM);
  456.   CORE_ADDR save_address;
  457.   REGISTER_TYPE buffer;
  458.   link->next = linked_proc_desc_table;
  459.   linked_proc_desc_table = link;
  460. #define PUSH_FP_REGNUM 16 /* must be a register preserved across calls */
  461. #define GEN_REG_SAVE_MASK MASK(1,16)|MASK(24,28)|(1<<31)
  462. #define GEN_REG_SAVE_COUNT 22
  463. #define FLOAT_REG_SAVE_MASK MASK(0,19)
  464. #define FLOAT_REG_SAVE_COUNT 20
  465. #define SPECIAL_REG_SAVE_COUNT 4
  466.   /*
  467.    * The registers we must save are all those not preserved across
  468.    * procedure calls. Dest_Reg (see tm-mips.h) must also be saved.
  469.    * In addition, we must save the PC, and PUSH_FP_REGNUM.
  470.    * (Ideally, we should also save MDLO/-HI and FP Control/Status reg.)
  471.    *
  472.    * Dummy frame layout:
  473.    *  (high memory)
  474.    *     Saved PC
  475.    *    Saved MMHI, MMLO, FPC_CSR
  476.    *    Saved R31
  477.    *    Saved R28
  478.    *    ...
  479.    *    Saved R1
  480.    *    Saved D18 (i.e. F19, F18)
  481.    *    ...
  482.    *    Saved D0 (i.e. F1, F0)
  483.    *    CALL_DUMMY (subroutine stub; see m-mips.h)
  484.    *    Parameter build area (not yet implemented)
  485.    *  (low memory)
  486.    */
  487.   PROC_REG_MASK(proc_desc) = GEN_REG_SAVE_MASK;
  488.   PROC_FREG_MASK(proc_desc) = FLOAT_REG_SAVE_MASK;
  489.   PROC_REG_OFFSET(proc_desc) = /* offset of (Saved R31) from FP */
  490.       -sizeof(long) - 4 * SPECIAL_REG_SAVE_COUNT;
  491.   PROC_FREG_OFFSET(proc_desc) = /* offset of (Saved D18) from FP */
  492.       -sizeof(double) - 4 * (SPECIAL_REG_SAVE_COUNT + GEN_REG_SAVE_COUNT);
  493.   /* save general registers */
  494.   save_address = sp + PROC_REG_OFFSET(proc_desc);
  495.   for (ireg = 32; --ireg >= 0; )
  496.     if (PROC_REG_MASK(proc_desc) & (1 << ireg))
  497.       {
  498.     buffer = read_register (ireg);
  499.     write_memory (save_address, &buffer, sizeof(REGISTER_TYPE));
  500.     save_address -= 4;
  501.       }
  502.   /* save floating-points registers */
  503.   save_address = sp + PROC_FREG_OFFSET(proc_desc);
  504.   for (ireg = 32; --ireg >= 0; )
  505.     if (PROC_FREG_MASK(proc_desc) & (1 << ireg))
  506.       {
  507.     buffer = read_register (ireg);
  508.     write_memory (save_address, &buffer, 4);
  509.     save_address -= 4;
  510.       }
  511.   write_register (PUSH_FP_REGNUM, sp);
  512.   PROC_FRAME_REG(proc_desc) = PUSH_FP_REGNUM;
  513.   PROC_FRAME_OFFSET(proc_desc) = 0;
  514.   buffer = read_register (PC_REGNUM);
  515.   write_memory (sp - 4, &buffer, sizeof(REGISTER_TYPE));
  516.   buffer = read_register (HI_REGNUM);
  517.   write_memory (sp - 8, &buffer, sizeof(REGISTER_TYPE));
  518.   buffer = read_register (LO_REGNUM);
  519.   write_memory (sp - 12, &buffer, sizeof(REGISTER_TYPE));
  520.   buffer = read_register (FCRCS_REGNUM);
  521.   write_memory (sp - 16, &buffer, sizeof(REGISTER_TYPE));
  522.   sp -= 4 * (GEN_REG_SAVE_COUNT+FLOAT_REG_SAVE_COUNT+SPECIAL_REG_SAVE_COUNT);
  523.   write_register (SP_REGNUM, sp);
  524.   PROC_LOW_ADDR(proc_desc) = sp - CALL_DUMMY_SIZE + CALL_DUMMY_START_OFFSET;
  525.   PROC_HIGH_ADDR(proc_desc) = sp;
  526.   SET_PROC_DESC_IS_DUMMY(proc_desc);
  527.   PROC_PC_REG(proc_desc) = RA_REGNUM;
  528. }
  529.  
  530. void
  531. mips_pop_frame()
  532. { register int regnum;
  533.   FRAME frame = get_current_frame ();
  534.   CORE_ADDR new_sp = frame->frame;
  535.   mips_extra_func_info_t proc_desc = (mips_extra_func_info_t)frame->proc_desc;
  536.   if (PROC_DESC_IS_DUMMY(proc_desc))
  537.     {
  538.       struct linked_proc_info **ptr = &linked_proc_desc_table;;
  539.       for (; &ptr[0]->info != proc_desc; ptr = &ptr[0]->next )
  540.       if (ptr[0] == NULL) abort();
  541.       *ptr = ptr[0]->next;
  542.       free (ptr[0]);
  543.       write_register (HI_REGNUM, read_memory_integer(new_sp - 8, 4));
  544.       write_register (LO_REGNUM, read_memory_integer(new_sp - 12, 4));
  545.       write_register (FCRCS_REGNUM, read_memory_integer(new_sp - 16, 4));
  546.     }
  547.   write_register (PC_REGNUM, FRAME_SAVED_PC(frame));
  548.   if (frame->proc_desc) {
  549.     for (regnum = 32; --regnum >= 0; )
  550.       if (PROC_REG_MASK(proc_desc) & (1 << regnum))
  551.     write_register (regnum,
  552.           read_memory_integer (frame->saved_regs->regs[regnum], 4));
  553.     for (regnum = 64; --regnum >= 32; )
  554.       if (PROC_FREG_MASK(proc_desc) & (1 << regnum))
  555.     write_register (regnum,
  556.           read_memory_integer (frame->saved_regs->regs[regnum], 4));
  557.   }
  558.   write_register (SP_REGNUM, new_sp);
  559.   flush_cached_frames ();
  560.   set_current_frame (create_new_frame (new_sp, read_pc ()));
  561. }
  562.  
  563. static
  564. mips_print_register(regnum, all)
  565.      int regnum, all;
  566. {
  567.       unsigned char raw_buffer[8];
  568.       REGISTER_TYPE val;
  569.  
  570.       read_relative_register_raw_bytes (regnum, raw_buffer);
  571.  
  572.       if (!(regnum & 1) && regnum >= FP0_REGNUM && regnum < FP0_REGNUM+32) {
  573.       read_relative_register_raw_bytes (regnum+1, raw_buffer+4);
  574.       printf_filtered ("(d%d: ", regnum&31);
  575.       val_print (builtin_type_double, raw_buffer, 0,
  576.              stdout, 0, 1, 0, Val_pretty_default);
  577.       printf_filtered ("); ", regnum&31);
  578.       }
  579.       fputs_filtered (reg_names[regnum], stdout);
  580. #ifndef NUMERIC_REG_NAMES
  581.       if (regnum < 32)
  582.       printf_filtered ("(r%d): ", regnum);
  583.       else
  584. #endif
  585.       printf_filtered (": ");
  586.  
  587.       /* If virtual format is floating, print it that way.  */
  588.       if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT
  589.       && ! INVALID_FLOAT (raw_buffer, REGISTER_VIRTUAL_SIZE(regnum))) {
  590.       val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0,
  591.              stdout, 0, 1, 0, Val_pretty_default);
  592.       }
  593.       /* Else print as integer in hex.  */
  594.       else
  595.     {
  596.       long val;
  597.  
  598.       bcopy (raw_buffer, &val, sizeof (long));
  599.       if (val == 0)
  600.         printf_filtered ("0");
  601.       else if (all)
  602.         printf_filtered ("0x%x", val);
  603.       else
  604.         printf_filtered ("0x%x=%d", val, val);
  605.     }
  606. }
  607.  
  608. /* Replacement for generic do_registers_info.  */
  609. mips_do_registers_info (regnum, fpregs)
  610.      int regnum;
  611.      int fpregs;
  612. {
  613.   if (regnum != -1) {
  614.       mips_print_register (regnum, 0);
  615.       printf_filtered ("\n");
  616.   }
  617.   else {
  618.       for (regnum = 0; regnum < NUM_REGS; ) {
  619.       if ((!fpregs) && regnum >= FP0_REGNUM && regnum <= FCRIR_REGNUM) {
  620.         regnum++;
  621.         continue;
  622.       }
  623.       mips_print_register (regnum, 1);
  624.       regnum++;
  625.       if ((regnum & 3) == 0 || regnum == NUM_REGS)
  626.           printf_filtered (";\n");
  627.       else
  628.           printf_filtered ("; ");
  629.       }
  630.   }
  631. }
  632. /* Return number of args passed to a frame. described by FIP.
  633.    Can return -1, meaning no way to tell.  */
  634.  
  635. mips_frame_num_args(fip)
  636.     FRAME fip;
  637. {
  638. #if 0
  639.     struct chain_info_t *p;
  640.  
  641.     p = mips_find_cached_frame(FRAME_FP(fip));
  642.     if (p->valid)
  643.         return p->the_info.numargs;
  644. #endif
  645.     return -1;
  646. }
  647.  
  648.  
  649. /* Bad floats: Returns 0 if P points to a valid IEEE floating point number,
  650.    1 if P points to a denormalized number or a NaN. LEN says whether this is
  651.    a single-precision or double-precision float */
  652. #define SINGLE_EXP_BITS  8
  653. #define DOUBLE_EXP_BITS 11
  654. int
  655. isa_NAN(p, len)
  656.      int *p, len;
  657. {
  658.   int exponent;
  659.   if (len == 4)
  660.     {
  661.       exponent = *p;
  662.       exponent = exponent << 1 >> (32 - SINGLE_EXP_BITS - 1);
  663.       return ((exponent == -1) || (! exponent && *p));
  664.     }
  665.   else if (len == 8)
  666.     {
  667.       exponent = *(p+1);
  668.       exponent = exponent << 1 >> (32 - DOUBLE_EXP_BITS - 1);
  669.       return ((exponent == -1) || (! exponent && *p * *(p+1)));
  670.     }
  671.   else return 1;
  672. }
  673.  
  674. /* To skip prologues, I use this predicate. Returns either PC
  675.    itself if the code at PC does not look like a function prologue,
  676.    PC+4 if it does (our caller does not need anything more fancy). */
  677.  
  678. CORE_ADDR mips_skip_prologue(pc)
  679.      CORE_ADDR pc;
  680. {
  681.     struct symbol *f;
  682.     struct block *b;
  683.     unsigned long inst;
  684.  
  685.     /* For -g modules and most functions anyways the
  686.        first instruction adjusts the stack. */
  687.     inst = read_memory_integer(pc, 4);
  688.     if ((inst & 0xffff0000) == 0x27bd0000)
  689.     return pc + 4;
  690.  
  691.     /* Well, it looks like a frameless. Let's make sure.
  692.        Note that we are not called on the current PC,
  693.        but on the function`s start PC, and I have definitely
  694.        seen optimized code that adjusts the SP quite later */
  695.     b = block_for_pc(pc);
  696.     if (!b) return pc;
  697.  
  698.     f = lookup_symbol(".gdbinfo.", b, LABEL_NAMESPACE, 0, NULL);
  699.     if (!f) return pc;
  700.     /* Ideally, I would like to use the adjusted info
  701.        from mips_frame_info(), but for all practical
  702.        purposes it will not matter (and it would require
  703.        a different definition of SKIP_PROLOGUE())
  704.  
  705.        Actually, it would not hurt to skip the storing
  706.        of arguments on the stack as well. */
  707.     if (((struct mips_extra_func_info *)f->value.value)->framesize)
  708.     return pc + 4;
  709.  
  710.     return pc;
  711. }
  712. @
  713.